#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <dlfcn.h>
#include <time.h>
#include <math.h>

#include "common.h"
#include "log4cplus.h"
#include "watchdog.h"

// 定义函数指针类型，与动态库接口一致
typedef int (*WdtLoadDriverFunc)();
typedef int (*WdtUnloadDriverFunc)();
typedef int (*WdtStartFunc)();
typedef int (*WdtStopFunc)();
typedef int (*WdtFeedFunc)(int time, int unit);
typedef int (*WdtStatusFunc)();

// 函数指针变量
static WdtLoadDriverFunc wdt_load_driver_func = NULL;
static WdtUnloadDriverFunc wdt_unload_driver_func = NULL;
static WdtStartFunc wdt_start_func = NULL;
static WdtStopFunc wdt_stop_func = NULL;
static WdtFeedFunc wdt_feed_func = NULL;
static WdtStatusFunc wdt_status_func = NULL;

// 动态库句柄
static void* wdt_lib_handle = NULL;

// 时间间隔控制
static int feedWait(int feedTime) {
    static time_t lastFeedTime = 0;
    time_t now = time(NULL);

    int dt = (int)difftime(now, lastFeedTime);
    if (abs(dt) >= feedTime) {
        lastFeedTime = now;
        return 1;
    }
    return 0;
}

// 加载动态库并获取函数地址
int wdtLoadLibrary(const char* lib_path) {
    wdt_lib_handle = dlopen(lib_path, RTLD_LAZY);
    if (!wdt_lib_handle) {
        log_error_fmt("Failed to load library %s: %s", lib_path, dlerror());
        return -1;
    }

    // 加载函数符号
    wdt_load_driver_func = (WdtLoadDriverFunc)dlsym(wdt_lib_handle, "wdt_load_driver");
    wdt_unload_driver_func = (WdtUnloadDriverFunc)dlsym(wdt_lib_handle, "wdt_unload_driver");
    wdt_start_func = (WdtStartFunc)dlsym(wdt_lib_handle, "wdt_start");
    wdt_stop_func = (WdtStopFunc)dlsym(wdt_lib_handle, "wdt_stop");
    wdt_feed_func = (WdtFeedFunc)dlsym(wdt_lib_handle, "wdt_feed");
    wdt_status_func = (WdtStatusFunc)dlsym(wdt_lib_handle, "wdt_status");

    // 检查是否有错误
    char* error;
    if ((error = dlerror()) != NULL) {
        log_error_fmt("Failed to load functions: %s", error);
        dlclose(wdt_lib_handle);
        return -1;
    }

    return 0;
}

// 卸载动态库
void wdtUnloadLibrary() {
    if (wdt_lib_handle) {
        dlclose(wdt_lib_handle);
        wdt_lib_handle = NULL;
    }
}

// 替换原有静态函数的实现
int wdtLoadDriver() {
    if (!wdt_load_driver_func) {
        log_error_fmt("Function not loaded: wdt_load_driver");
        return -1;
    }
    return wdt_load_driver_func();
}

int wdtUnloadDriver() {
    if (!wdt_unload_driver_func) {
        log_error_fmt("Function not loaded: wdt_unload_driver");
        return -1;
    }
    return wdt_unload_driver_func();
}

int wdtStart() {
    if (!wdt_start_func) {
        log_error_fmt("Function not loaded: wdt_start");
        return -1;
    }
    return wdt_start_func();
}

int wdtStop() {
    if (!wdt_stop_func) {
        log_error_fmt("Function not loaded: wdt_stop");
        return -1;
    }
    return wdt_stop_func();
}

int wdtFeed(int feedTime, int rebootTime) {
    if (!wdt_feed_func) {
        log_error_fmt("Function not loaded: wdt_feed");
        return -1;
    }

    if (feedWait(feedTime) == 0) {
        return 0;
    }

    int ret = wdt_feed_func(rebootTime, 0);
    if (ret != 0) {
        log_error_fmt("watchdog feed failure");
        return -1;
    }
    log_info_fmt("feed dog successfully. reboot time set to [%d] seconds.", 
                 rebootTime);

    return 0;
}

int wdtStatus() {
    if (!wdt_status_func) {
        log_error_fmt("Function not loaded: wdt_status");
        return -1;
    }
    return wdt_status_func();
}
